Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [php] Klient -> Serwer, problemy z przesyłem danych
gutek84
post
Post #1





Grupa: Zarejestrowani
Postów: 116
Pomógł: 4
Dołączył: 9.10.2007
Skąd: Morąg

Ostrzeżenie: (0%)
-----


Czy możliwe jest wykonanie w php aplikacji klient -> serwer?
Mam napisane 2 klasy.
Klasa serwer:
  1. <?php
  2. class Serwer{
  3.  
  4. private $gniazdko;
  5. private $adres = '127.0.0.1';
  6. private $port = 80;
  7. public $odebrane;
  8.  
  9. public function uruchomSerwer(){
  10. //Utworzenie gniazdka dla polaczenia TCP
  11. $this->gniazdko = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  12. socket_bind($this->gniazdko, $this->adres);
  13. socket_listen($this->gniazdko);
  14. if($this->gniazdko!== FALSE)echo "Uruchomiono!";
  15. }
  16.  
  17. public function odebrane(){
  18. socket_accept($this->gniazdko);
  19. $this->odebrane = socket_read($this->gniazdko, 2048);
  20. }
  21.  
  22. public function wylaczSerwer(){
  23. socket_close($this->gniazdko);
  24. echo "Zatrzymano!";
  25. }
  26.  
  27.  
  28. }
  29. ?>


Klasa Klient

  1. <?php
  2. class Klient{
  3. public $gniazdko;
  4. public $odebrane;
  5.  
  6. public function polacz($host){
  7. //Pobranie portu dla www
  8. $port = getservbyname('www', 'tcp');
  9. //pobranie adresu serwera
  10. $serwer = gethostbyname($host);
  11. //Utworzenie gniazdka dla polaczenia TCP
  12. $this->gniazdko = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  13. //Utworzenie połączenia
  14. $polaczenie = socket_connect($this->gniazdko, $serwer, $port);
  15. if($polaczenie!==False)echo"Polączono z serwerem!";
  16.  
  17. }
  18.  
  19.  
  20. public function rozlacz(){
  21. //Pobranie portu dla www
  22. socket_close($this->gniazdko);
  23.  
  24. }
  25.  
  26. public function wyslij($pakiet){
  27. //wysłanie danych
  28. socket_write($this->gniazdko, $pakiet, strlen($pakiet));
  29. }
  30.  
  31. public function odbierz(){
  32. //odbiór danych
  33. while($this->odebrane = socket_read($this->gniazdko, 2048)){
  34. echo $this->odebrane;
  35. };
  36. }
  37. }
  38. ?>


Problem następuje w momencie kiedy próbuje przesłać zapytanie od klienta do serwera! Nie wyskakują żadne warningi a skrypt serwera jakby sie wieszal w momencie proby odczytu!
Tak samo skrypt klienta w momencie wysylania takze sie zawiesza.

Prosze o pomoc!
Go to the top of the page
+Quote Post
Kicok
post
Post #2





Grupa: Zarejestrowani
Postów: 1 033
Pomógł: 125
Dołączył: 17.09.2005
Skąd: Żywiec

Ostrzeżenie: (0%)
-----


Nie wiem dokładnie co może być przyczyną tego zawieszania, bo nie pokazałeś nam najistotniejszego kodu - wywołania metod tych klas. Mogę co najwyżej przypuszczać, że dzieje się coś takiego:
- serwer nasłuchuje
- klient łączy się i wysyła powiedzmy 20 bajtów danych
- serwer odbiera te 20 bajtów, ale nie wie że to już koniec i czeka na następne
- klient w tym czasie czeka na odpowiedź serwera, więc nie zamyka połaczenia
- wszystko wisi


Wyjścia z tej sytuacji:
- Połączenia nieblokujące się, z tym że ty najprawdopodobniej chcesz, żeby serwer sobie działał gdzieś w tle i czekał spokojnie na połączenia. Wtedy coś takiego odpada. No ale poczytać możesz: (socket_set_nonblock" title="Zobacz w manualu PHP" target="_manual, socket_set_block" title="Zobacz w manualu PHP" target="_manual)
- Klient po wysłaniu danych nie czeka na odpowiedź tylko od razu zamyka połączenie (też w sumie odpada, bo wyjdzie z tego komunikacja jednostronna)
- Po wysłaniu danych wysyłasz jeszcze NULL (0x00). Serwer napotykając NULL kończy odbieranie danych i wysyła odpowiedź (też zakończona NULL-em). Problem jest taki, że NULL nie może wystąpić w przesyłanych danych
- I najlepsze: ustalasz sobie jakąś strukturę pakietów przesyłanych między serwerem a klientem, np:
Kod
Nagłówek
- typ_pakietu [1 bajt]
- długość_pakietu [4 bajty]
Ciało
- treść_pakietu [długość_pakietu]

Po odczytaniu długości ciała pakietu zarówno serwer jak i klient wiedzą ile jeszcze bajtów danych muszą odebrać. Przydatne funkcje: pack" title="Zobacz w manualu PHP" target="_manual, unpack" title="Zobacz w manualu PHP" target="_manual


PS. socket_get_option" title="Zobacz w manualu PHP" target="_manual i socket_set_option" title="Zobacz w manualu PHP" target="_manual też mogą się przydać.

Ten post edytował Kicok 25.07.2008, 13:05:28


--------------------
"Sumienie mam czyste, bo nieużywane."
Go to the top of the page
+Quote Post
gutek84
post
Post #3





Grupa: Zarejestrowani
Postów: 116
Pomógł: 4
Dołączył: 9.10.2007
Skąd: Morąg

Ostrzeżenie: (0%)
-----


Zmienilem klase Serwer na
  1. <?php
  2. class Serwer{
  3.  
  4. private $gniazdko;
  5. private $adres = '127.0.0.1';
  6. private $port = 80;
  7. public $odebrane;
  8.  
  9. public function uruchomSerwer(){
  10. //Utworzenie gniazdka dla polaczenia TCP
  11. $this->gniazdko = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  12. socket_set_blocking($this->gniazdko);
  13. socket_set_option($this->gniazdko, SOL_SOCKET, SO_REUSEADDR, 1);
  14. socket_bind($this->gniazdko, $this->adres, $this->port);
  15. socket_listen($this->gniazdko,1);
  16.  
  17. while(true){
  18.  
  19. $klient =socket_accept($this->gniazdko);
  20. echo "klient przyszedl";
  21. }
  22. if($this->gniazdko!== FALSE)echo "Uruchomiono!";
  23. }
  24.  
  25. public function odebrane(){
  26.  
  27. while($this->odebrane = socket_read($this->gniazdko, 2048)){
  28. echo $this->odebrane;
  29. };
  30.  
  31. }
  32.  
  33. public function wylaczSerwer(){
  34. echo "Zatrzymano!";
  35. socket_close($this->gniazdko);
  36.  
  37.  
  38.  
  39. }
  40.  
  41. }
  42.  
  43. ?>


Wiec nie dostaje zadnych bledow przy serwerze i kliencie. Jednak kiedy klient wysyla to serwer nie odbiera. Polaczenie jest akceptowane lecz nie ma komunikacji miedzy stronami. Uzywam socket_read i socket_write do przesylania danych.

Druga strona to jak mozna zrobic dynamiczny serwer.
Ten powyzszy dziala jak mam timeout na 10 to wyglada jakby przez 10 sekund ladowala sie strona. Interesuje mnie klient przychdzi i od razu go widze np. przed uplywem 10 sekund.

Ten post edytował gutek84 25.07.2008, 18:11:20
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 21.08.2025 - 04:41